package edu.pg.ipse.kb.frame.core;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class Slot {

    private String name;
    private Object value;
    private String help;
    private SlotType type = SlotType.NUMBER;

    private Frame frame;

    private IFunction function;
    private List<Demon> demons = new ArrayList<Demon>();

    public Slot(String name) {
        this.name = name;
    }

    public ResultType test() {

        switch(type) {
            case BOOL:
                if((Boolean) getValue()) {
                    return ResultType.YES;
                } else {
                    return ResultType.NO;
                }
            case NUMBER:
            case SYMBOLIC:
                if(getValue() != null)
                {
                    return ResultType.YES;
                }
                else
                {
                    return ResultType.NO;
                }
            case FRAME:
                if(value != null)
                {
                    return ((Frame) value).test();
                }
            case FUNCTION:
                if(value != null)
                {
                    Object result = ((IFunction) value).execute(null);
                    return result != null ? ResultType.YES : ResultType.NO;
                }
            default: break;
        }

        return ResultType.DO_NOT_KNOW;
    }

    // getters and setters

    public IFunction getFunction() {
        return function;
    }

    public void setFunction(IFunction function) {
        this.function = function;
    }

    public String getHelp() {
        return help;
    }

    public void setHelp(String help) {
        this.help = help;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Object getValue() {
        switch(type) {
            case NUMBER:
            case BOOL:
            case SYMBOLIC:
                if(value == null && demons != null) {
                    for(Demon demon : demons) {
                        if(demon.type == DemonType.IF_NEEDED)
                        {
                            return demon.execute(null);
                        }
                    }
                }
                break;
            default: break;
        }
        
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public void addDemon(Demon demon) {

        if(demon != null && !demons.contains(demon))
        {
            demon.slot = this;
            demons.add(demon);
        }   
    }

    public SlotType getType() {
        return type;
    }

    public void setType(SlotType type) {
        this.type = type;
    }

    public Frame getFrame() {
        return frame;
    }

    public void setFrame(Frame frame) {
        this.frame = frame;
    }


    
}
